package android_testsuite.mytest.rsa;

import android.content.Context;
import android.os.Environment;
import android.util.Base64;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import android_testsuite.R;

/**
 * @author Ren Hui
 * @since 1.0.1.058
 */
public class RsaEncrypt {
    private static final String DECODE_ALGO = "RSA";
    //最大明文加密块的大小
    private static final int MAX_ENCRYPT_BLOCK = 117;
    private Context mContext;
    private String mContent;
    private String PRIVATE_KEY_PKCS8 =
            "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKjcBbOR4EF908b2" +
            "lNnhxanfYWD7JO5z4q1O+JGl+EXWhezNQe/TGVMbRoWc3DAaKl7tjvHSgiJtDHBg" +
            "EpIUoyvu4eLFjWEF4+840DAw7UkD30lRj4UpVvHewIPgzPz/8jO23ae2jXpBrvU8" +
            "3p8eOmV0IgjJ+WyywW26JaUFkloPAgMBAAECgYBpHZZbA3tDqa2U1NkyjS48Ijd/" +
            "ZLfHzNIWKuvn1xanevShxeC/B31jU75h3JThSNiJgX6ToQSro5Czv8qvrzMnWY5c" +
            "dZc/K7ec2QHzx6rQzFnsRDD4ZsFvNKvZGGD14n8tl6ObQxFy/mdc1G0Xx+YKifM8" +
            "qkLwcYXoUVF7z9qgUQJBAOB6mWXdHjhREEjjVclbcCLRrTVUMgGS8fwdOtoA/3RM" +
            "J0gguNkuPpquTvtqtW6fLSbbqXqhIWhDtiVN/9ulbpkCQQDAkg6FaMJXj8rlt5Ld" +
            "staLNQANEEsrRKFjzS9JAo5P/5RMpRUgEgtRMkOgg0dos0Tm7Ny8ufWo6iZNRw50" +
            "pr7nAkBymeSKfpKZCbmYnIcFX2smO4mD+lH1P8HOhlWvSmcgRmifiCUWq2dGrMqh" +
            "zF6H9Tel6OrjMjPN+ROag/GlfxWxAkEAkeUWQ1TfCF/UpL2z82suyEDbTQpvKNTS" +
            "QT6O+I2LLGjB/l+D5cxF7rpaKh3L2DMZnKsPgZyR1euwIRQYi6BZOQJBAKIgjA9l" +
            "bRGMdVKo4LlpO/8nML7IeMGmV4ALyeBPCKIuqNnJUJ2Y5K4811tBO38q2QE49ZVj" +
            "2UTebziZ29vbuCs=";

    public RsaEncrypt(Context context) {
        super();
        mContext = context;
        //TODO [Ren Hui]:加密的内容直接放在代码里面，需要获取的内容是android机器中生成的文件。
        mContent = "-----BEGIN RSA PRIVATE KEY-----\n" +
                "MIICXQIBAAKBgQDDufmw57R+8/zCf5dAdBdmm8heZM0xpLZX5p6Q/7shWoxIk2aw\n" +
                "kscIZgpmx20qm17XmkcU0qgBOyEq/SIZ8MYlqVcAjFU2hmMAH7laub1CdgL4TPdO\n" +
                "QBLsMSzFMfnxdrK610teBdQLBw89udiXWmso5PbvGjzPRNw74OTXJ1i14QIDAQAB\n" +
                "AoGBAMMYqAlsjQBW2EZPxEac8Y54Dhv5QogPdSrdWIWUQ8WVamwVcbDkPbzjac7V\n" +
                "Tr2/raQfxma9LHY9qGwfclSFKhw1ZXCHvU4/BCZJOHhgvWNEiz7u7SX+Rv2Tn1Dq\n" +
                "FY2TNsUQ49KGF1ewSFAqlBZKovQfN6/AaqPYZJ0Y9ZCkuKeZAkEA7JviBy2jCKYB\n" +
                "AlK8KHKIbbLP6gDwRwAy0HR1ilxZLM8Gy/ol64L5n2dtUWTFeA4+VXBY1eqSRLXA\n" +
                "jN4sClmcswJBANPEXi4yaGQPiYWRT/2f09WL//+o03IC8pUIVMJnGe13iwoFRGJ6\n" +
                "ZYcJjiMywaRQxdc7mckaxTzf1eK9EyQLlRsCQC+BJKJYUVFdMvqqbciZJjcQHZpX\n" +
                "0eYPbiRYHXlIDUdn0W+Gq7JbO477jwE2gEcYZP92bP+V9wQAkcY2nRT+5O0CQBGX\n" +
                "SkuEHG/TapUR0Rc8Y5hlnMpb99SMsiH3IzNS5TB4sbAPZ/LWQADLpmb+HF/N5eFP\n" +
                "LiMqeh/oaBgBpMllvOkCQQDgpzG+0mTj85Op4YoBxq90SVKSUJsDJNTe1gImUl2H\n" +
                "cIU6M2UOqYuKB48YImPGCU9S78vRD+jZS3BFRDSIsjBF\n" +
                "-----END RSA PRIVATE KEY-----\n";
    }

    public String encodeToBase64() {
        if (mContent == null || mContent.equals("")) {
            String err = mContext.getResources().getString(R.string.rsa_encrypt_tip);
            return err;
        }

        byte[] data = mContent.getBytes();  //得到所需要的加密信息
        String encodeContent = "";   //存储加密后结果
        String result = "";  //存储编码结果
        RSAPrivateKey privateKey;
        //解码秘钥
        byte[] privateKeyContent = Base64.decode(PRIVATE_KEY_PKCS8, Base64.DEFAULT);
        PKCS8EncodedKeySpec x509 = new PKCS8EncodedKeySpec(privateKeyContent);

        try {
            KeyFactory keyFactory = KeyFactory.getInstance(DECODE_ALGO);
            privateKey = (RSAPrivateKey) keyFactory.generatePrivate(x509);
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            //记录要加密的文件的总长度
            int inputLen = data.length;
            //游标
            int offSet = 0;
            //记录每次的生成
            byte[] cache;
            //开始加密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                    //进行RSA加密
                    cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                    //将加密结果编码成Base64码
                    encodeContent = new String(Base64.encode(cache, Base64.NO_WRAP));
                } else {
                    cache = cipher.doFinal(data, offSet, inputLen - offSet);
                    encodeContent = new String(Base64.encode(cache, Base64.NO_WRAP));
                }
                result += encodeContent;
                offSet += MAX_ENCRYPT_BLOCK;
            }

            File file = new File(Environment.getExternalStorageDirectory().getPath() + "/EncryptResult.txt");
            file.createNewFile();
            FileOutputStream out = new FileOutputStream(file);
            out.write(result.getBytes());
            out.close();
        } catch (java.security.NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //输出到日志文件中
        Log.d("encodeContent", result);
        return result;
    }
}
